package com.huizu.pay.util;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alipay.api.CertAlipayRequest;
import com.alipay.api.domain.AlipayFundTransUniTransferModel;
import com.alipay.api.domain.Participant;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.huizu.common.core.domain.AjaxResult;
import com.huizu.pay.util.pay.AliPay.PayConstants;
import com.huizu.pay.util.pay.wxpay.sdk.WxPayEnumConfig;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.wxpay.sdk.WXPay;

//zhangmx
public class PayInterface {


	private static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");

	/**
	 * 支付宝预下单
	 *
	 * @param orderMap
	 * @return
	 */
	public static AjaxResult insertAlipayPay(Map<String, Object> orderMap) {
		AjaxResult payMap = new AjaxResult();
		try {
			String url = String.valueOf(orderMap.get("url"));
			String price = orderMap.get("price").toString();
			String orderCode = String.valueOf(orderMap.get("orderCode")); // 预下单订单编号
			if (orderMap != null && orderMap.size() > 0) {
//				AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, app_id,
//						merchant_private_key, "json", AlipayConfig.charset, alipay_public_key, AlipayConfig.sign_type);
				AlipayClient alipayClient = PayConstants.getAlipayClient();
				// 拼个账单添加账单请勿重新值
				AlipayTradeAppPayRequest alipayRequest = new AlipayTradeAppPayRequest();
				AlipayTradeAppPayModel alipayTradeAppPayModel = new AlipayTradeAppPayModel();
				alipayTradeAppPayModel.setBody("商品");
				alipayTradeAppPayModel.setSubject("商品");
				alipayTradeAppPayModel.setOutTradeNo(orderCode);
				alipayTradeAppPayModel.setTimeoutExpress("30m");
				alipayTradeAppPayModel.setTotalAmount(price);
				alipayTradeAppPayModel.setProductCode("FACE_TO_FACE_PAYMENT");// QUICK_MSECURITY_PAY // FACE_TO_FACE_PAYMENT
				alipayRequest.setBizModel(alipayTradeAppPayModel);
				alipayRequest.setNotifyUrl(url);
				AlipayTradeAppPayResponse response = alipayClient.sdkExecute(alipayRequest);
				if (response.isSuccess()) {
					payMap.put("orderInfo", response.getBody());// 返回打印信息
					payMap.put("orderCode", orderCode);
					payMap.put("code", 200);
					payMap.put("msg", "预下单成功");
				}
			} else {
				payMap.put("code", 500);
				payMap.put("msg", "预下单失败");
			}
		} catch (AlipayApiException e) {
			payMap.put("msg", "预下单失败");
			payMap.put("code", 500);
			e.printStackTrace();
		}
		return payMap;
	}

	/**
	 * 支付宝H5预下单
	 *
	 * @param orderMap
	 * @return
	 * @throws AlipayApiException
	 */
	public static Map<String, Object> insertH5AlipayPay(Map<String, Object> orderMap)  {
		Map<String, Object> payMap = new HashMap<>();
		try {
			String url = String.valueOf(orderMap.get("url"));
			String price = orderMap.get("price").toString();
			String orderCode = String.valueOf(orderMap.get("orderCode")); // 预下单订单编号

//			AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl,app_id,merchant_private_key,"json","utf-8",alipay_public_key,"RSA2");
			AlipayClient alipayClient = PayConstants.getAlipayClient();
			AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
			request.setNotifyUrl(url);
			request.setReturnUrl("http://mhyanshih5.menghuan.art/#/pages/payment_wancheng/payment_wancheng");
			/*JSONObject bizContent = new JSONObject();
			bizContent.put("out_trade_no", orderCode);
			bizContent.put("total_amount",price);
			bizContent.put("subject", "商品");
			bizContent.put("product_code", "QUICK_WAP_WAY");
			bizContent.put("body", "商品");
			request.setBizContent(bizContent.toJSONString(0));*/
			String subject = "商品";
			String body ="商品";
			request.setBizContent("{\"out_trade_no\":\"" + orderCode + "\","
					+ "\"total_amount\":\"" + price + "\","
					+ "\"subject\":\"" + subject + "\","
					+ "\"body\":\"" + body + "\","
					+ "\"product_code\":\"QUICK_MSECURITY_PAY\"}");
			AlipayTradeWapPayResponse response = alipayClient.certificateExecute(request);
			System.err.println("==========="+url);
			if(response.isSuccess()){
				System.err.println("调用成功");
				payMap.put("orderInfo", response.getBody());
				payMap.put("orderCode", orderCode);
			} else {
				payMap.put("code", 1);
				payMap.put("msg", "预下单失败");
			}
		}catch(AlipayApiException e){
			payMap.put("msg", "预下单失败");
			payMap.put("code", 1);
			e.printStackTrace();
		}

		return payMap;
	}

	// 支付宝回调
	public static Map<String, Object> alipayNotifyUrl(HttpServletRequest request) {
		Map<String, String> params = new HashMap<>();
		Map<String, Object> orderMap = new HashMap<>();
		try {
			params = analysisParams(request);
			orderMap = new HashMap<String, Object>();
//			boolean signVerified = AlipaySignature.rsaCheckV1(params, alipay_public_key, AlipayConfig.charset,
//					AlipayConfig.sign_type);
			boolean signVerified = AlipaySignature.certVerifyV1(params, PayConstants.ALI_PAY_PUBLIC_KEY, AlipayConfig.charset,
					AlipayConfig.sign_type);
			String paramsJson = JSON.toJSONString(params);
			System.out.println("=======333==========="+paramsJson);
			if (signVerified) {
				orderMap = getAlipayOrderCodeInfo(request);
				if ("TRADE_SUCCESS".equals(orderMap.get("trade_status"))) {
					if (orderMap.containsKey("out_trade_no")) {
						orderMap.put("orderCode", orderMap.get("out_trade_no"));
						orderMap.put("code", 200);
					} else {
						orderMap.put("code", 500);
					}
				} else {
					orderMap.put("code", 500);
				}
			} else {
				orderMap.put("code", 500);
			}
		} catch (Exception e) {
			orderMap.put("code", 500);
			e.printStackTrace();
		}
		return orderMap;
	}

	/**
	 * 支付宝支付完成回调地址（异步回调） 校验支付宝是否真正支付成功
	 *
	 * @param request
	 */
	public static Map<String, String> analysisParams(HttpServletRequest request) throws UnsupportedEncodingException {
		Map<String, String> params = new HashMap<String, String>();
		Map<String, String[]> requestParams = request.getParameterMap();
		for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
			}
			params.put(name, valueStr);
		}
		return params;
	}

	// 支付宝退款
	public static int alipayRefund(String orderCode, String totalPrice) throws AlipayApiException {

//		AlipayClient alipayClient = new DefaultAlipayClient(SERVER_URL, APP_ID, ALIPAY_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, ALIPAY_SEAL);
//		AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
//		request.setOutTradeNo(outTradeNo); // 商户订单号或者支付宝交易号
//		request.setRefundAmount(refundAmount); // 申请退款金额
//		request.setRefundReason(refundReason); // 申请退款理由
//		return alipayClient.pageExecute(request);

//		AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
//				PayConstants.ALI_PAY_APP_ID, PayConstants.ALI_PAY_MERCHANT_PRIVATE_KEY, "json", "utf-8",
//				PayConstants.ALI_PAY_PUBLIC_KEY, "RSA2"); // 获得初始化的AlipayClient
		AlipayClient alipayClient = PayConstants.getAlipayClient();
		AlipayTradeRefundModel refundModel = new AlipayTradeRefundModel();
		refundModel.setOutTradeNo(orderCode);
		refundModel.setRefundAmount(totalPrice);
		refundModel.setRefundReason("商品退款");
		refundModel.setRefundAmount(totalPrice);
		AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();//证书模式
//		AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
		request.setBizModel(refundModel);
		AlipayTradeRefundResponse response = alipayClient.certificateExecute(request);
//		AlipayTradeRefundResponse response = alipayClient.execute(request);
		System.out.println(response.getBody());
		if ("Success".equals(response.getMsg()))
			return 0;
		else
			return 1;
	}

	/**
	 * 提现打款
	 * @param map
	 * @return
	 * @throws Exception
	 */
	public static Map<String,Object> alipayWithdraw(Map<String,Object> map) throws Exception {
		Map<String,Object> respMap = new HashMap<>();
		String name = String.valueOf(map.get("name"));
		String phone = String.valueOf(map.get("phone"));
		String orderId = String.valueOf(map.get("orderId"));
		String price  = String.valueOf(map.get("price"));

		AlipayClient alipayClient = PayConstants.getAlipayClient();

		AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
		AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();

		//提现订单号自己定义 商家侧唯一订单号，由商家自定义。
		model.setOutBizNo(orderId);
//        SignData signData = new SignData();
//        //商户订单号
//        signData.setOriOutBizNo("商户订单号");
//        signData.setOriSignType("RSA2");
//        signData.setOriSign("EqHFP0z4a9iaQ1ep==");
//        signData.setOriCharSet("UTF-8");
//        //签名被授权方支付宝账号ID
//        signData.setPartnerId("z17753083939@163.com");
//        //固定 签名商户开放平台应用APPID  2021000185629012
//        signData.setOriAppId(appid);
//        //签名
//        model.setSignData(signData);

		model.setRemark("搭兑-转账");
		//原支付宝业务单号。C2C现金红包-红包领取时，传红包支付时返回的支付宝单号；B2C现金红包、单笔无密转账到支付宝不需要该参数。
//        model.setOriginalOrderId("20190620110075000006640000063056");
		//转账业务请求的扩展参数，支持传入的扩展参数如下： sub_biz_scene 子业务场景，红包业务必传，取值REDPACKET，C2C现金红包、B2C现金红包均需传入
		model.setBusinessParams("{\"sub_biz_scene\":\"REDPACKET\"}");
		//描述特定的业务场景，可传的参数如下： DIRECT_TRANSFER：单笔无密转账到支付宝，B2C现金红包; PERSONAL_COLLECTION：C2C现金红包-领红包
		model.setBizScene("DIRECT_TRANSFER");

		//收款方信息
		Participant payeeInfo = new Participant();
		//参与方的唯一标识
		//参与方的标识类型，目前支持如下类型 1、ALIPAY_USER_ID 支付宝的会员ID 2、ALIPAY_LOGON_ID：支付宝登录号，支持邮箱和手机号格式 3、ALIPAY_OPEN_ID：支付宝
		payeeInfo.setIdentityType("ALIPAY_LOGON_ID");
		payeeInfo.setIdentity(phone);
		payeeInfo.setName(name);
		model.setPayeeInfo(payeeInfo);
		//转账金额 订单总金额，单位为元
		model.setTransAmount(price);
		//业务产品码， 单笔无密转账到支付宝账户固定为: TRANS_ACCOUNT_NO_PWD； 收发现金红包固定为: STD_RED_PACKET；
		model.setProductCode("TRANS_ACCOUNT_NO_PWD");
		model.setOrderTitle("搭兑-转账");
		request.setBizModel(model);

		AlipayFundTransUniTransferResponse response = alipayClient.certificateExecute(request);
		System.err.println(response.getBody());
		if (response.isSuccess()) {
			System.out.println("调用成功");
		} else {
			System.out.println("调用失败");
			// sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
			// String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
			// System.out.println(diagnosisUrl);
		}
		com.alibaba.fastjson2.JSONObject dataJson = com.alibaba.fastjson2.JSONObject.parseObject(response.getBody());
		com.alibaba.fastjson2.JSONObject responseJson = com.alibaba.fastjson2.JSONObject.parseObject(dataJson.get("alipay_fund_trans_uni_transfer_response").toString());
		String code = String.valueOf(responseJson.get("code"));
		String sub_msg = String.valueOf(responseJson.get("sub_msg"));
		String msg = String.valueOf(responseJson.get("msg"));
		if ("10000".equals(code)&&"Success".equals(msg)){
			respMap.put("code",200);
			respMap.put("msg","提现成功");
			return respMap;
		}
		else {
			respMap.put("code",200);
			respMap.put("msg",sub_msg);
			return respMap;
		}
	}


	//查询订单信息
	public static int alipayReturn(Map<String,Object> map) throws Exception {
		int i=0;
//		AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl,app_id,merchant_private_key,"json","utf-8",alipay_public_key,"RSA2");
		AlipayClient alipayClient = PayConstants.getAlipayClient();
		AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
		JSONObject bizContent = new JSONObject();
		bizContent.put("out_trade_no", map.get("orderCode"));
		request.setBizContent(bizContent.toString());
		AlipayTradeQueryResponse response = alipayClient.certificateExecute(request);
		if(response.isSuccess()){
			System.out.println("调用成功");
			String body=response.getBody();
			System.err.println(body);
			ObjectMapper mapper = new ObjectMapper();
			Map<String,Object> m=mapper.readValue(body, Map.class);
			Map<String,Object> m1=(Map<String, Object>) m.get("alipay_trade_query_response");
			System.out.println(m1.get("out_trade_no"));
			i=1;
			return i;
		} else {
			return i;
			//System.out.println("调用失败");
		}

	}

	//查询订单信息
	public static Map<String,Object> alipayReturn1(Map<String,Object> map) throws Exception {
//			AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl,app_id,merchant_private_key,"json","utf-8",alipay_public_key,"RSA2");
		AlipayClient alipayClient = PayConstants.getAlipayClient();
		AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
		JSONObject bizContent = new JSONObject();
		bizContent.put("out_trade_no", map.get("orderCode"));
		request.setBizContent(bizContent.toString());
		AlipayTradeQueryResponse response = alipayClient.certificateExecute(request);
		if(response.isSuccess()){
			System.out.println("调用成功");
			String body=response.getBody();
			ObjectMapper mapper = new ObjectMapper();
			Map<String,Object> m=mapper.readValue(body, Map.class);
			Map<String,Object> m1=(Map<String, Object>) m.get("alipay_trade_query_response");
			System.out.println(m1.get("out_trade_no"));
			m1.put("orderCode", m1.get("out_trade_no"));
			return m1;
		} else {
			return null;
		}

	}

	//查询订单信息
	public static Map<String,Object> alipayReturn2(Map<String,Object> map) throws Exception {
//		AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl,app_id,merchant_private_key,"json","utf-8",alipay_public_key,"RSA2");
		AlipayClient alipayClient = PayConstants.getAlipayClient();
		AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
		JSONObject bizContent = new JSONObject();
		bizContent.put("trade_no", map.get("zhifuCode"));
		request.setBizContent(bizContent.toString());
		AlipayTradeQueryResponse response = alipayClient.certificateExecute(request);
		if(response.isSuccess()){
			System.out.println("调用成功");
			String body=response.getBody();
			ObjectMapper mapper = new ObjectMapper();
			Map<String,Object> m=mapper.readValue(body, Map.class);
			Map<String,Object> m1=(Map<String, Object>) m.get("alipay_trade_query_response");
			System.out.println(m1.get("out_trade_no"));
			m1.put("orderCode", m1.get("out_trade_no"));
			return m1;
		} else {
			return null;
		}

	}

	/**
	 * 获取支付宝订单信息
	 *
	 * @param request
	 * @return
	 */
	public static Map<String, Object> getAlipayOrderCodeInfo(HttpServletRequest request) {
		Map<String, Object> orderMap = new HashMap<String, Object>();
		String out_trade_no = request.getParameter("out_trade_no");// 商户订单号
		String trade_no = request.getParameter("trade_no");// 支付宝交易号
		String total_amount = request.getParameter("total_amount");// 付款金额
		String timestamp = request.getParameter("timestamp");
		String trade_status = request.getParameter("trade_status");
		orderMap.put("out_trade_no", out_trade_no);
		orderMap.put("trade_no", trade_no);
		orderMap.put("total_amount", total_amount);
		orderMap.put("timestamp", timestamp);
		orderMap.put("trade_status", trade_status);
		return orderMap;
	}
	
	

	/// ======================微信=================================
	/**
	 * 微信app预下单
	 * 
	 * @return
	 * @throws Exception
	 */
	public static AjaxResult insertWeChatPay(Map<String, Object> orderMap, HttpServletRequest request)
			throws Exception {
		MyAppConfig myAppConfig = new MyAppConfig();
		WXPay wxpay = new WXPay(myAppConfig);
		AjaxResult hashMap = new AjaxResult();
		SortedMap<String, Object> signMap = new TreeMap<>();// 生成签名信息
		Map<String, String> dataMap = new HashMap<>();// 微信订单信息
		Map<String, Object> payMap = new HashMap<>();// 接口返回信息
		String orderCode = String.valueOf(orderMap.get("orderCode"));
		String url = String.valueOf(orderMap.get("url"));
		String price = orderMap.get("price").toString();
		if (orderMap != null && orderMap.size() > 0) {
			try {
				String nonceStr = getNonceStr();// 随机字符串
				String spbillCreateIp = getClientIP(request);// 访问IP
				signMap = insertSignInfo(nonceStr);// 生成签名信息
				dataMap.put("appid", WxPayEnumConfig.app_appId);
				dataMap.put("mch_id", WxPayEnumConfig.mch_id);
				dataMap.put("nonce_str", nonceStr);
				dataMap.put("body", "商品");
				dataMap.put("out_trade_no", orderCode);
				dataMap.put("total_fee", queryWxOrderPrice(price));
				dataMap.put("spbill_create_ip", spbillCreateIp);
				dataMap.put("notify_url", url);
				dataMap.put("trade_type", "APP");
				dataMap.put("sign", createSign(signMap, WxPayEnumConfig.private_key));
				System.err.println(dataMap);
				Map<String, String> resp = wxpay.unifiedOrder(dataMap);// 请求微信预支付接口，生成订单
				System.err.println(resp);
				if ("SUCCESS".equals(resp.get("result_code")) && "SUCCESS".equals(resp.get("return_code"))) {
					String appId = StringSplit.objectToString(resp.get("appid"));
					String mchId = StringSplit.objectToString(resp.get("mch_id"));
					String noncestr = StringSplit.objectToString(resp.get("nonce_str"));
					String prepayId = StringSplit.objectToString(resp.get("prepay_id"));
					long timeStamp = new Date().getTime() / 1000;// 当前时间戳
					signMap = insertSignInfoAgain(appId, mchId, prepayId, noncestr, timeStamp);// 生成签名信息
					hashMap.put("code", 200);
					hashMap.put("msg", "预下单成功");
					payMap.put("appId", appId);// 公众账号ID
					payMap.put("mchId", mchId);// 商户号
					payMap.put("nonceStr", noncestr);// 随机字符串
					payMap.put("prepayId", prepayId);// 预支付交易会话标识
					payMap.put("orderCode", orderCode);// 订单编号
					payMap.put("tradeType", StringSplit.objectToString(resp.get("trade_type")));// 交易类型
					payMap.put("sign", createSign(signMap, WxPayEnumConfig.private_key));// 微信签名
					payMap.put("timeStamp", timeStamp);
					hashMap.put("data", payMap);
				}
			} catch (Exception e) {
				hashMap.put("code", 500);
				hashMap.put("msg", "预下单失败");
				e.printStackTrace();
			}
		}
		return hashMap;
	}

	// 微信小程序支付
	public static AjaxResult payOrder(Map<String, Object> pm) throws Exception {
		AjaxResult map = new AjaxResult();
		SortedMap<String, Object> parameters = new TreeMap<String, Object>();
		String totalPrice = queryWxOrderPrice(String.valueOf(pm.get("price")));
		String url = String.valueOf(pm.get("url"));
		parameters.put("appid", WxPayEnumConfig.wx_appId);
		parameters.put("mch_id", WxPayEnumConfig.mch_id);
		//parameters.put("sub_mch_id", sub_mch_id);
		parameters.put("nonce_str", getNonceStr());// 签名
		parameters.put("body", "商品");// 商品描述
		parameters.put("out_trade_no", String.valueOf(pm.get("orderCode")));// 订单号
		parameters.put("total_fee", totalPrice);// 金额
		parameters.put("spbill_create_ip", WxPayEnumConfig.create_ip);// 终端IP
		parameters.put("notify_url", url);// 回调地址
		parameters.put("trade_type", "JSAPI");
		parameters.put("openid", String.valueOf(pm.get("openId")));
		parameters.put("sign", createSign(parameters, WxPayEnumConfig.private_key));
		String result = postData(WxPayEnumConfig.unifiedorder, getRequestXml(parameters));
		System.out.println(result);
		SortedMap<String, Object> rem = XmlUtil.doXMLParse(result);
		if ("SUCCESS".equals(rem.get("return_code").toString())
				&& "SUCCESS".equals(rem.get("result_code").toString())) {
			String prepay_id = rem.get("prepay_id").toString();
			//createPackageValue(WxPayEnumConfig.app_appId, WxPayEnumConfig.private_key, prepay_id);
			if (prepay_id != null && prepay_id.length() > 10) {
				ObjectMapper mapper = new ObjectMapper();
				String res = createPackageValue(WxPayEnumConfig.wx_appId, WxPayEnumConfig.private_key, prepay_id);
				map.put("data",mapper.readValue(res, Map.class));
//				map = mapper.readValue(res, Map.class);
				map.put("code", "200");
				map.put("msg", "预下成功");
			}
		} else {
			map.put("code", 500);
			map.put("msg", "预下单失败");
		}
		return map;
	}
	
	
	//微信H5支付
	
	public static String getCodeUrl(Map<String,Object> pm) throws Exception {
		/**
		 * 账号信息
		 */
		String trade_type = "MWEB"; // 类型 扫码支付【网页扫码支付NATIVE】H5支付的交易类型为MWEB
		String time_expire = sdf.format(3 * 60 * 1000 + System.currentTimeMillis()); // 交易结束时间
		/**
		 * 时间字符串
		 */
		String currTime = sdf.format(new Date());
		String strTime = currTime.substring(8, currTime.length());
		String strRandom = buildRandom(4) + "";
		String nonce_str = strTime + strRandom;
		String price = pm.get("price").toString();
		int totalAmount = (new BigDecimal(price).multiply(new BigDecimal("100"))).intValue();
		String url = String.valueOf(pm.get("url"));
		String openId = String.valueOf(pm.get("memberId"));
		String ip=String.valueOf(pm.get("ip"));
		String scene_info = "{\"h5_info\": {\"type\":\"Wap\",\"wap_url\": \"https://pay.qq.com\",\"wap_name\": \"腾讯充值\"}} ";
		/**
		 * 参数封装
		 * 
		 * 
		 * location /{
			proxy_pass	http://localhost:8016/;
			proxy_set_header x-forwarded-for  $remote_addr;

		}
		 */
		SortedMap<String, Object> packageParams = new TreeMap<String, Object>();
		packageParams.put("appid", WxPayEnumConfig.app_appId);
		packageParams.put("mch_id", WxPayEnumConfig.mch_id);
		packageParams.put("nonce_str", nonce_str);// 随机字符串
		packageParams.put("body", "商品下单");// 支付的商品名称
		packageParams.put("out_trade_no", String.valueOf(pm.get("orderCode")));// 商户订单号【备注：每次发起请求都需要随机的字符串，否则失败。】
		packageParams.put("total_fee", "" + totalAmount);// 支付金额
		packageParams.put("notify_url", url);
		packageParams.put("trade_type", trade_type);
		packageParams.put("attach", openId);// 额外的参数【业务类型+会员ID+支付类型】
		packageParams.put("time_expire", time_expire);
		packageParams.put("scene_info", scene_info);
		packageParams.put("spbill_create_ip", "192.168.1.50");
		String sign =createSign(packageParams, WxPayEnumConfig.private_key); // 获取签名
		packageParams.put("sign", sign);
		String requestXML = getRequestXml(packageParams);// 将请求参数转换成String类型
		String resXml = postData(WxPayEnumConfig.unifiedorder, requestXML); // 解析请求之后的xml参数并且转换成String类型
		Map map = XmlUtil.doXMLParse(resXml);
		System.err.println(resXml);
		// 预下单 获取接口地址
		String return_code = (String) map.get("return_code");
		String return_msg = (String) map.get("return_msg");
		if ("SUCCESS".equals(return_code) && "OK".equals(return_msg)) {
			String urlCode = (String) map.get("mweb_url");
			// 支付完返回浏览器跳转的地址，如跳到查看订单页面
			String redirect_url = "http://wwv.menghuan.art/pages/tabBar/index/index";
			String redirect_urlEncode = URLEncoder.encode(redirect_url, "utf-8");// 对上面地址urlencode
			urlCode = urlCode + "&redirect_url=" + redirect_urlEncode;// 拼接返回地址
			return urlCode;
		} else {
			System.out.println("统一支付接口获取预支付订单出错");
			return "获取预支付订单出错";
		}
	}

	/**
	 * 微信支付完成回调地址
	 *
	 * @param request
	 * @param response
	 */
	@Transactional
	public Map<String, Object> wxTradePagePayNotifyUrl(HttpServletRequest request, HttpServletResponse response)
			throws IOException {
		Map<String, Object> map = new HashMap<>();
		String string;
		InputStream inputStream;
		StringBuffer stringBuffer = new StringBuffer();
		inputStream = request.getInputStream();
		BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
		while ((string = bufferedReader.readLine()) != null)
			stringBuffer.append(string);
		bufferedReader.close();
		inputStream.close();
		Map<String, Object> xmlMap = new HashMap<String, Object>();
		xmlMap = XmlUtil.doXMLParse(stringBuffer.toString());// 解析xml成map
		SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
		Iterator it = xmlMap.keySet().iterator();
		while (it.hasNext()) {
			String str = "";
			String parameter = (String) it.next();
			String parameterValue = String.valueOf(xmlMap.get(parameter));
			if (null != parameterValue)
				str = parameterValue.trim();
			packageParams.put(parameter, str);
		}
		if (PayCommonUtil.isTenpaySign("UTF-8", packageParams, WxPayEnumConfig.private_key)) {
			String resXml = "";
			if ("SUCCESS".equals((String) packageParams.get("result_code"))) {
				resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
						+ "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
				System.out.println("这是微信回调显示报文已成功");
				if (packageParams.containsKey("out_trade_no")) {
					String orderCode = (String) packageParams.get("out_trade_no");
					map.put("code", 200);
					map.put("orderCode", orderCode);
				}
			} else {
				System.out.println("这是微信支付失败");
				resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
						+ "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
				map.put("code", 500);
			}
			BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
			out.write(resXml.getBytes());
			out.flush();
			out.close();
		}
		return map;
	}

	// 退款
	public static int wxRefund(String orderCode, String totalFee, String refundFee) throws Exception {
		HashMap<String, String> map = new HashMap<>();
		MyAppConfig myAppConfig = new MyAppConfig();
		WXPay wxPay = new WXPay(myAppConfig);
		map.put("out_trade_no", orderCode);
		map.put("total_fee", queryWxOrderPrice(totalFee));
		map.put("refund_fee", queryWxOrderPrice(refundFee));
		map.put("out_refund_no", orderCode);
		Map<String, String> refund = wxPay.refund(map);
		if ("SUCCESS".equals(refund.get("return_code")) && "SUCCESS".equals(refund.get("result_code"))) {
			return 200;
		} else {
			return 500;
		}
	}
	
	//查询订单
	public static int wxPayOrder(Map<String,Object> param) throws Exception{
		HashMap<String, String> map = new HashMap<>();
		MyAppConfig myAppConfig = new MyAppConfig();
		WXPay wxPay = new WXPay(myAppConfig);
		map.put("mchid", WxPayEnumConfig.mch_id);
		map.put("out_trade_no", String.valueOf(param.get("orderCode")));
		System.out.println(param.get("orderCode"));
		Map<String, String> refund = wxPay.orderQuery(map);
		System.out.println(refund);
		if ("SUCCESS".equals(refund.get("return_code")) && "SUCCESS".equals(refund.get("result_code"))) {
			System.out.println(1);
			return 1;
		} else {
			System.out.println(0);
			return 0;
		}
	}

	/*
	 * 随机字符窜
	 */
	public static String getNonceStr() {
		String timeStamp = String.valueOf((new Date().getTime()));
		String randomStr = String.valueOf(new Random().nextInt(100000));
		String nonceStr = Md5Util.MD5Encode(timeStamp.concat(randomStr), "utf-8");
		int maxLength = nonceStr.length() > 32 ? 32 : nonceStr.length();
		return nonceStr.substring(0, maxLength);
	}

	// 分析IP
	public static String getClientIP(HttpServletRequest httpservletrequest) {
		if (httpservletrequest == null)
			return null;
		String s = httpservletrequest.getHeader("X-Forwarded-For");
		if (s == null || s.length() == 0 || "unknown".equalsIgnoreCase(s))
			s = httpservletrequest.getHeader("Proxy-Client-IP");
		if (s == null || s.length() == 0 || "unknown".equalsIgnoreCase(s))
			s = httpservletrequest.getHeader("WL-Proxy-Client-IP");
		if (s == null || s.length() == 0 || "unknown".equalsIgnoreCase(s))
			s = httpservletrequest.getHeader("HTTP_CLIENT_IP");
		if (s == null || s.length() == 0 || "unknown".equalsIgnoreCase(s))
			s = httpservletrequest.getHeader("HTTP_X_FORWARDED_FOR");
		if (s == null || s.length() == 0 || "unknown".equalsIgnoreCase(s))
			s = httpservletrequest.getRemoteAddr();
		if ("127.0.0.1".equals(s) || "0:0:0:0:0:0:0:1".equals(s))
			try {
				s = InetAddress.getLocalHost().getHostAddress();
			} catch (UnknownHostException unknownhostexception) {
				unknownhostexception.printStackTrace();
			}
		if (s.indexOf(",") != -1)
			s = s.substring(0, s.indexOf(","));
		return s;
	}

	/**
	 * 微信支付签名
	 *
	 * @param nonceStr
	 * @return
	 */
	private static SortedMap<String, Object> insertSignInfo(String nonceStr) {
		SortedMap<String, Object> signMap = new TreeMap<>();// 生成签名信息
		signMap.put("appid", WxPayEnumConfig.app_appId);
		signMap.put("mch_id", WxPayEnumConfig.mch_id);
		signMap.put("nonce_str", nonceStr);
		return signMap;
	}

	// 微信元转分
	private static String queryWxOrderPrice(String orderMap) {
		// 元为单位 转换为分为单位
		// 元为单位 转换为分为单位
		BigDecimal orderPrice = new BigDecimal(String.valueOf(orderMap)).multiply(new BigDecimal(100));
		return orderPrice.setScale(0, BigDecimal.ROUND_HALF_UP).toString();// 订单金额
	}

	public static String createSign(SortedMap<String, Object> packageParams, String API_KEY) {
		StringBuffer sb = new StringBuffer();
		Set<Map.Entry<String, Object>> es = packageParams.entrySet();
		Iterator<Map.Entry<String, Object>> it = es.iterator();
		while (it.hasNext()) {
			Map.Entry<String, Object> entry = (Map.Entry<String, Object>) it.next();
			Object ok = entry.getKey();
			String k = ok == null ? null : ok.toString();
			Object ov = entry.getValue();
			String v = ov == null ? null : ov.toString();
			if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
				sb.append(k + "=" + v + "&");
			}
		}
		sb.append("key=" + API_KEY);
		String sign = Md5Util.MD5Encode(sb.toString(), "utf-8").toUpperCase();
		return sign;
	}

	private static SortedMap<String, Object> insertSignInfoAgain(String appId, String mchId, String prepayId,
			String noncestr, long timeStamp) {
		SortedMap<String, Object> signMap = new TreeMap<>();// 生成签名信息
		signMap.put("appid", appId);
		signMap.put("partnerid", mchId);
		signMap.put("prepayid", prepayId);
		signMap.put("noncestr", noncestr);
		signMap.put("timestamp", timeStamp);
		signMap.put("package", "Sign=WXPay");
		return signMap;
	}

	public static String getRequestXml(SortedMap<String, Object> parameters) {
		StringBuffer sb = new StringBuffer();
		sb.append("<xml>");
		Set<Entry<String, Object>> es = parameters.entrySet();
		Iterator<Entry<String, Object>> it = es.iterator();
		while (it.hasNext()) {
			Map.Entry<String, Object> entry = (Map.Entry<String, Object>) it.next();
			Object ok = entry.getKey();
			String k = ok == null ? null : ok.toString();
			Object ov = entry.getValue();
			String v = ov == null ? null : ov.toString();
			if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {
				sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");
			} else {
				sb.append("<" + k + ">" + v + "</" + k + ">");
			}
		}
		sb.append("</xml>");
		return sb.toString();
	}

	public static String postData(String urlStr, String data) {
		BufferedReader reader = null;
		try {
			URL url = new URL(urlStr);
			URLConnection conn = url.openConnection();
			conn.setDoOutput(true);
			conn.setConnectTimeout(5000);
			conn.setReadTimeout(5000);
			conn.setDoInput(true);
			OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
			if (data == null)
				data = "";
			writer.write(data);
			writer.flush();
			writer.close();

			reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
			StringBuilder sb = new StringBuilder();
			String line = null;
			while ((line = reader.readLine()) != null) {
				sb.append(line);
				sb.append("\r\n");
			}
			return sb.toString();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (reader != null)
					reader.close();
			} catch (IOException e) {
			}
		}
		return null;
	}

	public static String createPackageValue(String appid, String appKey, String prepay_id) {
		// 封装调用支付接口所需参数
		SortedMap<String, Object> nativeObj = new TreeMap<String, Object>();
		nativeObj.put("appId", appid);
		nativeObj.put("timeStamp", Long.toString(new Date().getTime() / 1000));// 时间戳
		// 生成随机数
		Random random = new Random();
		String data = String.valueOf(random.nextInt(10000));
		String randomStr = Md5Util.MD5Encode(data, "utf-8").toUpperCase();
		nativeObj.put("nonceStr", Md5Util.MD5Encode(randomStr, "utf-8").toLowerCase());// 随机字符串
		nativeObj.put("package", "prepay_id=" + prepay_id);// prepay_id
		nativeObj.put("signType", "MD5");//
		nativeObj.put("paySign", createSign(nativeObj, appKey));// 签名
		nativeObj.put("code", "0");
		nativeObj.put("msg", "签名成功");
		return net.sf.json.JSONObject.fromObject(nativeObj).toString();
	}
	
	 public static int buildRandom(int length) {
	        int num = 1;
	        double random = Math.random();
	        if (random < 0.1) {
	            random = random + 0.1;
	        }
	        for (int i = 0; i < length; i++) {
	            num = num * 10;
	        }
	        return (int) ((random * num));
	    }

}
